/*
 * Copyright (C) Francisco Morero Peyrona. All rights reserved.
 *
 * This software is published under the terms of Open Source 
 * License version 1.1, a copy of which has been included with this
 * distribution in the License.txt file.  
 */

package jdbcmanager.table;

import java.io.*;
import java.math.*;
import java.net.*;
import java.sql.*;
import java.sql.Date;
import java.util.*;

/**
 * An implementation of ResulySet that stores informarion in memory.
 * 
 * @author Francisco Morero Peyrona
 */

public class RowSetRam implements ResultSet
{
   private ResultSet rs    = null;
   private Vector    vData = new Vector();
   private int       nRow  = -1;          // Selected row (0 >= nRow < vData.size())

   public RowSetRam( ResultSet rs ) throws SQLException
   {
      this( rs, 256 );
   }

   public RowSetRam( ResultSet rs, int nMaxRows ) throws SQLException
   {
      int nCols = rs.getMetaData().getColumnCount();

      if( nMaxRows <= 0 || nMaxRows > 3000 )
         nMaxRows = 3000;
      
      while( rs.next() && this.vData.size() < nMaxRows )
      {
         Vector vRow = new Vector();

         for( int n = 1; n <= nCols; n++ )
            vRow.add( rs.getObject( n ) );

         this.vData.add( vRow );
      }

      this.rs   = rs;
      this.nRow = -1;   // 0 == 1st record, and can't be positioned there until user invokes rs.next()
   }

   public boolean next()
   {
      if( this.vData.size() > 0 &&
          this.nRow + 1 < this.vData.size() )
      {
         this.nRow++;
         return true;
      }

      return false;
   }

   public void close() throws SQLException
   {
      this.vData.removeAllElements();
      this.vData = null;
      this.nRow  = -1;
      this.rs.close();
   }

   public boolean wasNull()  { throw new java.lang.UnsupportedOperationException("Method wasNull() not yet implemented."); }
   
   public String getString( int columnIndex ) throws SQLException
   {
      return getObject( columnIndex - 1 ).toString();
   }

   public boolean getBoolean(int columnIndex) { throw new java.lang.UnsupportedOperationException("Method getBoolean() not yet implemented."); }
   public byte getByte(int columnIndex) { throw new java.lang.UnsupportedOperationException("Method getByte() not yet implemented."); }
   public short getShort(int columnIndex) { throw new java.lang.UnsupportedOperationException("Method getShort() not yet implemented."); }
   public int getInt(int columnIndex) { throw new java.lang.UnsupportedOperationException("Method getInt() not yet implemented."); }
   public long getLong(int columnIndex) { throw new java.lang.UnsupportedOperationException("Method getLong() not yet implemented."); }
   public float getFloat(int columnIndex) { throw new java.lang.UnsupportedOperationException("Method getFloat() not yet implemented."); }
   public double getDouble(int columnIndex) { throw new java.lang.UnsupportedOperationException("Method getDouble() not yet implemented."); }
   public BigDecimal getBigDecimal(int columnIndex, int scale) { throw new java.lang.UnsupportedOperationException("Method getBigDecimal() not yet implemented."); }
   public byte[] getBytes(int columnIndex) { throw new java.lang.UnsupportedOperationException("Method getBytes() not yet implemented."); }
   public Date getDate(int columnIndex) { throw new java.lang.UnsupportedOperationException("Method getDate() not yet implemented."); }
   public Time getTime(int columnIndex) { throw new java.lang.UnsupportedOperationException("Method getTime() not yet implemented."); }
   public Timestamp getTimestamp(int columnIndex) { throw new java.lang.UnsupportedOperationException("Method getTimestamp() not yet implemented."); }
   public InputStream getAsciiStream(int columnIndex) { throw new java.lang.UnsupportedOperationException("Method getAsciiStream() not yet implemented."); }
   public InputStream getUnicodeStream(int columnIndex) { throw new java.lang.UnsupportedOperationException("Method getUnicodeStream() not yet implemented."); }
   public InputStream getBinaryStream(int columnIndex) { throw new java.lang.UnsupportedOperationException("Method getBinaryStream() not yet implemented."); }

   public String getString(String columnName) throws SQLException
   {
      return getString( this.rs.findColumn( columnName ) );
   }

   public boolean getBoolean(String columnName) { throw new java.lang.UnsupportedOperationException("Method getBoolean() not yet implemented."); }
   public byte getByte(String columnName) { throw new java.lang.UnsupportedOperationException("Method getByte() not yet implemented."); }
   public short getShort(String columnName) { throw new java.lang.UnsupportedOperationException("Method getShort() not yet implemented."); }
   public int getInt(String columnName) { throw new java.lang.UnsupportedOperationException("Method getInt() not yet implemented."); }
   public long getLong(String columnName) { throw new java.lang.UnsupportedOperationException("Method getLong() not yet implemented."); }
   public float getFloat(String columnName) { throw new java.lang.UnsupportedOperationException("Method getFloat() not yet implemented."); }
   public double getDouble(String columnName) { throw new java.lang.UnsupportedOperationException("Method getDouble() not yet implemented."); }
   public BigDecimal getBigDecimal(String columnName, int scale) { throw new java.lang.UnsupportedOperationException("Method getBigDecimal() not yet implemented."); }
   public byte[] getBytes(String columnName) { throw new java.lang.UnsupportedOperationException("Method getBytes() not yet implemented."); }
   public Date getDate(String columnName) { throw new java.lang.UnsupportedOperationException("Method getDate() not yet implemented."); }
   public Time getTime(String columnName) { throw new java.lang.UnsupportedOperationException("Method getTime() not yet implemented."); }
   public Timestamp getTimestamp(String columnName) { throw new java.lang.UnsupportedOperationException("Method getTimestamp() not yet implemented."); }
   public InputStream getAsciiStream(String columnName) { throw new java.lang.UnsupportedOperationException("Method getAsciiStream() not yet implemented."); }
   public InputStream getUnicodeStream(String columnName) { throw new java.lang.UnsupportedOperationException("Method getUnicodeStream() not yet implemented."); }
   public InputStream getBinaryStream(String columnName)  { throw new java.lang.UnsupportedOperationException("Method getBinaryStream() not yet implemented."); }
   public SQLWarning getWarnings() { throw new java.lang.UnsupportedOperationException("Method getWarnings() not yet implemented."); }
   public void clearWarnings() { throw new java.lang.UnsupportedOperationException("Method clearWarnings() not yet implemented."); }
   
   public String getCursorName() throws SQLException
   {
      return this.rs.getCursorName();
   }

   public ResultSetMetaData getMetaData() throws SQLException
   {
      return this.rs.getMetaData();
   }

   public Object getObject( int columnIndex ) throws SQLException
   {
      if( this.vData.size() == 0 || this.nRow < 0 || this.nRow >= this.vData.size() )
         throw new SQLException( "Pointer is out of bounds." );

      return ((Vector) this.vData.get( nRow )).get( columnIndex - 1 );
   }

   public Object getObject(String columnName) throws SQLException
   {
      return getObject( this.rs.findColumn( columnName ) );
   }

   public int findColumn(String columnName) throws SQLException
   {
      return this.rs.findColumn( columnName );
   }

   public Reader getCharacterStream(int columnIndex) { throw new java.lang.UnsupportedOperationException("Method getCharacterStream() not yet implemented."); }
   public Reader getCharacterStream(String columnName) { throw new java.lang.UnsupportedOperationException("Method getCharacterStream() not yet implemented."); }
   public BigDecimal getBigDecimal(int columnIndex) { throw new java.lang.UnsupportedOperationException("Method getBigDecimal() not yet implemented."); }
   public BigDecimal getBigDecimal(String columnName) { throw new java.lang.UnsupportedOperationException("Method getBigDecimal() not yet implemented."); }

   public boolean isBeforeFirst()
   {
      return this.nRow <= -1;
   }

   public boolean isAfterLast()
   {
      return this.nRow >= this.vData.size();
   }

   public boolean isFirst()
   {
      return this.nRow == 0;
   }

   public boolean isLast()
   {
      return this.nRow == this.vData.size() - 1;
   }

   public void beforeFirst()
   {
      if( this.vData.size() > 0 )
         this.nRow = -1;
   }

   public void afterLast()
   {
      if( this.vData.size() > 0 )
         this.nRow = this.vData.size();
   }

   public boolean first()
   {
      if( this.vData.size() > 0 )
         this.nRow = 0;

      return this.vData.size() > 0;
   }

   public boolean last()
   {
      if( this.vData.size() > 0 )
         this.nRow = this.vData.size() - 1;

      return this.vData.size() > 0;
   }

   public int getRow()
   {
      return this.nRow + 1;
   }

   public boolean absolute( int row )
   {
      if( this.vData.size() > 0 &&
          row >= 1              &&
          row <= this.vData.size() )
      {
         this.nRow = row - 1;
         return true;
      }

      return false;
   }

   public boolean relative( int rows )
   {
      return absolute( getRow() + rows );
   }

   public boolean previous()
   {
      if( this.vData.size() > 0 && this.nRow > 0 )
      {
         this.nRow--;
         return true;
      }

      return false;
   }

   public void setFetchDirection( int direction ) { throw new java.lang.UnsupportedOperationException("Method setFetchDirection() not yet implemented."); }
   public int getFetchDirection() { throw new java.lang.UnsupportedOperationException("Method getFetchDirection() not yet implemented."); }
   public void setFetchSize(int rows) { throw new java.lang.UnsupportedOperationException("Method setFetchSize() not yet implemented."); }
   public int getFetchSize() { throw new java.lang.UnsupportedOperationException("Method getFetchSize() not yet implemented."); }
   
   public int getType()
   {
       return ResultSet.TYPE_SCROLL_INSENSITIVE;
   }

   public int getConcurrency()
   {
       return ResultSet.CONCUR_READ_ONLY;
   }
   
   public Statement getStatement() throws SQLException
   {
      return this.rs.getStatement();
   }

   public Object getObject(int i, Map map) { throw new java.lang.UnsupportedOperationException("Method getObject() not yet implemented."); }
   public Ref getRef(int i) { throw new java.lang.UnsupportedOperationException("Method getRef() not yet implemented."); }
   public Blob getBlob(int i) { throw new java.lang.UnsupportedOperationException("Method getBlob() not yet implemented."); }
   public Clob getClob(int i) { throw new java.lang.UnsupportedOperationException("Method getClob() not yet implemented."); }
   public Array getArray(int i) { throw new java.lang.UnsupportedOperationException("Method getArray() not yet implemented."); }
   public Object getObject(String colName, Map map) { throw new java.lang.UnsupportedOperationException("Method getObject() not yet implemented."); }
   public Ref getRef(String colName) { throw new java.lang.UnsupportedOperationException("Method getRef() not yet implemented."); }
   public Blob getBlob(String colName) { throw new java.lang.UnsupportedOperationException("Method getBlob() not yet implemented."); }
   public Clob getClob(String colName) { throw new java.lang.UnsupportedOperationException("Method getClob() not yet implemented."); }
   public Array getArray(String colName) {throw new java.lang.UnsupportedOperationException("Method getArray() not yet implemented.");}
   public Date getDate(int columnIndex, Calendar cal) { throw new java.lang.UnsupportedOperationException("Method getDate() not yet implemented."); }
   public Date getDate(String columnName, Calendar cal) { throw new java.lang.UnsupportedOperationException("Method getDate() not yet implemented."); }
   public Time getTime(int columnIndex, Calendar cal) { throw new java.lang.UnsupportedOperationException("Method getTime() not yet implemented."); }
   public Time getTime(String columnName, Calendar cal) { throw new java.lang.UnsupportedOperationException("Method getTime() not yet implemented."); }
   public Timestamp getTimestamp(int columnIndex, Calendar cal) { throw new java.lang.UnsupportedOperationException("Method getTimestamp() not yet implemented."); }
   public Timestamp getTimestamp(String columnName, Calendar cal) { throw new java.lang.UnsupportedOperationException("Method getTimestamp() not yet implemented."); }
   public URL getURL(int columnIndex) { throw new java.lang.UnsupportedOperationException("Method getURL() not yet implemented."); }
   public URL getURL(String columnName) { throw new java.lang.UnsupportedOperationException("Method getURL() not yet implemented."); }
   
   public boolean rowUpdated() { throw new java.lang.UnsupportedOperationException("Method rowUpdated() not yet implemented."); }
   public boolean rowInserted() { throw new java.lang.UnsupportedOperationException("Method rowInserted() not yet implemented."); }
   public boolean rowDeleted() { throw new java.lang.UnsupportedOperationException("Method rowDeleted() not yet implemented."); }
   public void updateNull(int columnIndex) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateBoolean(int columnIndex, boolean x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateByte(int columnIndex, byte x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateShort(int columnIndex, short x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateInt(int columnIndex, int x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateLong(int columnIndex, long x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateFloat(int columnIndex, float x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateDouble(int columnIndex, double x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateBigDecimal(int columnIndex, BigDecimal x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateString(int columnIndex, String x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateBytes(int columnIndex, byte[] x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateDate(int columnIndex, Date x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateTime(int columnIndex, Time x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateTimestamp(int columnIndex, Timestamp x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateAsciiStream(int columnIndex, InputStream x, int length) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateBinaryStream(int columnIndex, InputStream x, int length) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateCharacterStream(int columnIndex, Reader x, int length) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateObject(int columnIndex, Object x, int scale) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateObject(int columnIndex, Object x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateNull(String columnName) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateBoolean(String columnName, boolean x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateByte(String columnName, byte x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateShort(String columnName, short x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateInt(String columnName, int x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateLong(String columnName, long x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateFloat(String columnName, float x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateDouble(String columnName, double x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateBigDecimal(String columnName, BigDecimal x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateString(String columnName, String x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateBytes(String columnName, byte[] x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateDate(String columnName, Date x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateTime(String columnName, Time x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateTimestamp(String columnName, Timestamp x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateAsciiStream(String columnName, InputStream x, int length) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateBinaryStream(String columnName, InputStream x, int length) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateCharacterStream(String columnName, Reader reader, int length) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateObject(String columnName, Object x, int scale) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateObject(String columnName, Object x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateRef(int columnIndex, Ref x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateRef(String columnName, Ref x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateBlob(int columnIndex, Blob x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateBlob(String columnName, Blob x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateClob(int columnIndex, Clob x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateClob(String columnName, Clob x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateArray(int columnIndex, Array x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateArray(String columnName, Array x) { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void insertRow() { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void updateRow() { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void deleteRow() { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void cancelRowUpdates() { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void moveToInsertRow()  { throw new UnsupportedOperationException("Operation not allowed using MemoryRowSet."); }
   public void refreshRow() { throw new java.lang.UnsupportedOperationException("Method refreshRow() not yet implemented."); }
   public void moveToCurrentRow() { throw new java.lang.UnsupportedOperationException("Method moveToCurrentRow() not yet implemented."); }
}